from django.core.files.uploadedfile import InMemoryUploadedFile
from django.db import IntegrityError
from django.http import HttpResponse
from django.views import View
from rest_framework import status
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet

from goods_app.models import ImageFile, SKU
from user_app.serializers.Image import ImageSerializer
from utils.loadfile import handle_uploaded_file, handle_delete_file
from utils.rest_pagination import MyPagination


class ImageView(View):
    def get(self):
        pass

    def post(self, request):
        """
        保存图片
        数据需要通过form-data传递
        图片保存到存储器上
        url等数据保存在image_file表中
        :param request:
        :return: 图片url
        """
        sku_id = request.POST.get('sku_id')
        file = request.FILES.get('image')

        # ------- 参数检查 ----------
        if not all([sku_id, file]):
            return HttpResponse("参数不齐全")

        if not isinstance(file, InMemoryUploadedFile):
            return HttpResponse("file类型错误")

        # -------- 上传和保存 ----------
        try:
            url, key = handle_uploaded_file(file.read())
        except:
            return HttpResponse("file上传失败")

        try:
            sku = SKU.objects.get(id=sku_id)
            ImageFile.objects.create(url=url + key, f_sku=sku)
        except SKU.DoesNotExist:
            return HttpResponse("sku_id错误")
        except IntegrityError:
            return HttpResponse("database保存失败, sku已有图片数据")

        return HttpResponse(url + key)

    def put(self):
        pass

    def delete(self, request, pk):
        """
        删除文件
        删除存储器上的图片
        删除数据库上的image_file表的行
        pk ：sku对象的id
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        if not pk or not isinstance(pk, int):
            return HttpResponse("PK错误")

        try:
            sku = SKU.objects.get(id=pk)
            url = sku.image_file.url
            key = url.split('/')[-1]
        except SKU.DoesNotExist:
            return HttpResponse("未查询到sku")
        except SKU.image_file.RelatedObjectDoesNotExist:
            return HttpResponse("未查询到sku关联的图片数据")
        else:
            sku.image_file.delete()

        try:
            handle_delete_file(key)
        except Exception as e:
            return HttpResponse(e)

        return HttpResponse("删除成功")


class ImageViewREST(ModelViewSet):
    serializer_class = ImageSerializer
    queryset = ImageFile.objects.all()
    pagination_class = MyPagination

    def create(self, request, *args, **kwargs):
        """
        保存图片
        数据需要通过form-data传递
        图片保存到存储器上
        url等数据保存在image_file表中
        :param request:
        :return: 图片url
        """
        sku_id = request.POST.get('sku_id')
        file = request.FILES.get('image')

        # ------- 参数检查 ----------
        if not all([sku_id, file]):
            return Response("参数不齐全")

        if not isinstance(file, InMemoryUploadedFile):
            return Response("file类型错误")

        # -------- 上传和保存 ----------
        try:
            url, key = handle_uploaded_file(file.read())
        except:
            return Response("file上传失败")

        try:
            sku = SKU.objects.get(id=sku_id)
            ImageFile.objects.create(url=url + key, f_sku=sku)
        except SKU.DoesNotExist:
            return Response("sku_id错误")
        except IntegrityError:
            return Response("database保存失败, sku已有图片数据")

        return Response(url + key)

    def perform_destroy(self, instance):
        #     删除文件
        #     删除存储器上的图片
        #     删除数据库上的image_file表的行
        try:
            key = instance.url.split('/')[-1]
            handle_delete_file(key)
        except Exception as e:
            raise e
        else:
            instance.delete()

    def perform_update(self, serializer):
        """
        执行更新image_file表中的图片

        路径方式： file/<pk:image_id>
        参数方式：form-data key=image_file
        serializer：查询到的需要更新的 ImageFile对象
        :return:
        """

        try:
            file = self.request.FILES['image_file']
            url, key = handle_uploaded_file(file.read())
        except AttributeError as e:
            raise AttributeError("image文件错误")
        except KeyError as e:
            raise KeyError("表单key有误")
        except Exception as e:
            raise Exception("上传文件出错")
        serializer.save(url=url + key)
